package sf.jooq.dao;

import org.jooq.Condition;
import org.jooq.Delete;
import org.jooq.Insert;
import org.jooq.Record;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.Table;
import org.jooq.Update;
import sf.common.wrapper.Page;
import sf.core.DBObject;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;

public interface DBJooq {

    /**
     * jooq判断是否存在
     * @param sqlDialect 可以传null,主要是用于商业版需要传入.
     * @param condition
     * @param clz
     * @param <T>
     * @return
     */
    <T extends DBObject> boolean jooqExists(SQLDialect sqlDialect, List<Condition> condition, Class<T> clz);

    /**
     * jooq 查询单一对象
     * @param select      查询语句
     * @param returnClass 返回类型
     * @param <T>
     * @return
     */
    <T> T jooqSelectOne(Select<?> select, Class<T> returnClass);

    /**
     * jooq 查询list
     * @param select
     * @param returnClass
     * @param <T>
     * @return
     */
    <T> List<T> jooqSelectList(Select<?> select, Class<T> returnClass);

    /**
     * jooq 查询分页
     * @param countSelect 查询总数的select
     * @param pageSelect  查询列表的select,必须包含分页参数.
     * @param returnClass 返回值
     * @param <T>         返回值根据select的查询条件变化,可能为bean,单一值,或Map
     * @return
     * @
     */
    <T> Page<T> jooqSelectPage(Select<?> countSelect, Select<?> pageSelect, Class<T> returnClass);

    /**
     * jooq 查询按流返回
     * @param ormIt
     * @param beanClass
     * @param select
     * @param <T>
     */
    <T> void jooqSelectIterator(Consumer<Iterable<T>> ormIt, Class<T> beanClass, Select<?> select);

    /**
     * jooq 查询按流返回
     * @param ormStream
     * @param beanClass
     * @param select
     * @param <T>
     */
    <T> void jooqSelectStream(Consumer<Stream<T>> ormStream, Class<T> beanClass, Select<?> select);

    /**
     * jooq 插入
     * @param insert
     * @return
     */
    <T extends Record> int jooqInsert(Insert<T> insert);

    /**
     * 带返回值的插入
     * @param insert
     * @param table     使用的表
     * @param keyValues
     * @return
     */
    <T extends Record> int jooqInsert(Insert<T> insert, Table<T> table, Map<String, Object> keyValues);

    /**
     * jooq 更新
     * @param update
     * @return
     */
    <T extends Record> int jooqUpdate(Update<T> update);

    /**
     * jooq 删除
     * @param delete
     * @return
     */
    <T extends Record> int jooqDelect(Delete<T> delete);
}
